#!/usr/bin/python
# -*- coding: utf-8 -*-

#This file is part of pyLot library.
#
# pyLot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyLot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pyLot.  If not, see <http://www.gnu.org/licenses/>.

__author__ = u'Pierre Puiseux, Guillaume Baty'
__copyright__ = u"Copyright 2011-2012 (C) andheo, Université de Pau et des Pays de l'Adour"
__credits__ = [u'Pierre Puiseux', u'Guillaume Baty']
__license__ = "GNU Lesser General Public License"

__all__ = [
           'StdTerminalWriter',
           'NullWriter',
           'DebugLogger',
           'PipeLogger',
           ]

u"""
This module provide several :obj:`~logging.Logger`.
"""

import sys
from traits.api import implements

from _pylot.minimal.system import ENCODING
from _pylot.minimal.default.impl_streamwriter import StreamWriter
from .interfaces.i_logger import ILogger

import logging

class NullWriter (logging.Logger):
  u"""
  Black hole logger.
  This logger writes absolutely nothing !
  """
  implements(ILogger)

  def __init__ (self, name, level=logging.NOTSET):
    logging.Logger.__init__(self, name, level)
    try :
      handler = logging.NullHandler()
    except AttributeError :
      handler = logging.Handler()
    self.addHandler(handler)

  def write (self, text, style=u'std'):
    return

  def popup(self, title, desc=None, message=None):
    return

  def stdout(self, s):
    return

  def stderr(self, s):
    return

  def clear(self):
    return


class StdTerminalWriter(StreamWriter):
  u"""
  This logger is designed to write in terminal supporting colors.
  Colors are defined using escape characters like "\033[1;34m".
  
  ..warning ::
  
    - using this logger in separate threads may produce unexpected text colors.
    - redirecting this logger to a file do not remove escape chars.

  """

  def __init__(self, name, level=logging.NOTSET):
    logging.Logger.__init__(self, name, level=level)
    handler = logging.StreamHandler(sys.stdout)
    self.addHandler(handler)

  @classmethod
  def formatText (cls, text, style):
    if text is None :
      return ''

    if isinstance(text, unicode) :
      text = text.encode(ENCODING, u'replace')
    else :
      text = str(text)

    if style == u'title' :
      line = '-' * min(len(text), 80)
      text = '\n%s\n%s\n%s\n' % (line, text, line)
      text = '\033[1;34m%s\033[0;0m' % text
    elif style == u'warn':
      text = '\033[1;31m%s\033[0;0m' % text
    elif style == u'info':
      text = '\033[1;30m%s\033[0;0m' % text
    else :
      pass
    return text

  def clear(self):
    pass

  def write (self, text, style=u'std'):
    self.stdout(self.formatText(self.toStr(text), style))

  def popup(self, title, desc=None, message=None):
    u"""
    Message used to alert user
    """
    self.write(title, style=u'title')
    if desc :
      self.write(desc)
    if message :
      self.write(message, u'info')

  def stdout(self, s):
    u"""
    message sent to stdout by process.
    Generally redirected to sys.stdout
    """
    sys.stdout.write(s)
    sys.stdout.flush()

  def stderr(self, s):
    sys.stderr.write(s)
    sys.stderr.flush()

class PipeLogger(StdTerminalWriter):
  u"""
  Like StdTerminalWriter but also stores stdout and stderr in stdout_list and
  stderr_list.
  """

  def __init__(self, name, level=logging.NOTSET):
    StdTerminalWriter.__init__(self, name, level)
    self.clear()

  def clear(self):
    self.stdout_list = []
    self.stderr_list = []

  def write(self, text, style=u'std'):
    print self.formatText(self.toStr(text), style)

  def stdout(self, s):
    print s
    self.stdout_list.append(s)

  def stderr(self, s):
    print s
    self.stderr_list.append(s)

class DebugLogger(StreamWriter):
  u"""
  Logger useful to debug Loggers : method called is written before normal output
  """

  def __init__(self, name, level=logging.NOTSET):
    logging.Logger.__init__(self, name, level=level)
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(u'log:%(message)s')
    self.addHandler(handler)

  def clear(self):
    pass

  def write (self, text, style=u'std'):
    print 'write(text,style): %r, %r' % (text, style)

  def popup(self, title, desc=None, message=None):
    u"""
    Message used to alert user
    """
    print 'popup(title,desc,message): %r, %r, %s' % (title, desc, message)

  def stdout(self, s):
    u"""
    message sent to stdout by process.
    Generally redirected to sys.stdout
    """
    print 'stdout(s):', repr(s)

  def stderr(self, s):
    print 'stderr(s):', repr(s)


#    if style == u'title' :
#      line = '*' * 80
#      text = '%s\n%s\n%s\n' % (line, text, line)
#    elif style == u'warn':
#      text = '*** %s ***' % text
#    elif style == u'info':
#      text = '# %s' % text
#    else :
#      pass
#    return text
